package com.qlslylq.ad.sdk.net.interceptor;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.qlslylq.ad.sdk.BuildConfig;
import com.qlslylq.ad.sdk.util.GsonUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedHashMap;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;

/**
 * 网络层日志拦截器<br/>
 */
public class LoggerInterceptor implements Interceptor {

    private static final String TAG = LoggerInterceptor.class.getSimpleName();
    private static final Charset UTF8 = Charset.forName("UTF-8");

    private String tag;
    private boolean showResponse;

    public LoggerInterceptor(String tag) {
        this(tag, false);
    }

    public LoggerInterceptor(String tag, boolean showResponse) {
        if (TextUtils.isEmpty(tag)) {
            tag = TAG;
        }
        this.showResponse = showResponse;
        this.tag = tag;
    }

    private void printLongLog(String tag, Request request, Response response, String msg) {
        if (BuildConfig.DEBUG) {
            HashMap<String, Object> mDeviceCrashInfo = new LinkedHashMap<>();
            getPacket(mDeviceCrashInfo, request, response);
            Log.e(tag, "报文 : " + GsonUtils.gsonString(mDeviceCrashInfo));
            Log.e(tag, "数据 : " + msg);
        }
    }

    private HashMap getPacket(HashMap mDeviceCrashInfo, Request request, Response response) {
        try {
            String url_base = request.url().host();
            RequestBody requestBody = request.body();
            Charset charset = Charset.forName("UTF-8");
            Gson gson = GsonUtils.getGson();
            JsonObject jo_post_param = new JsonObject();

            Buffer buffer = new Buffer();
            if (requestBody != null) {
                requestBody.writeTo(buffer);
                MediaType contentType = requestBody.contentType();
                if (contentType != null && false) {
                    charset = contentType.charset();
                }

                String json_req_body = gson.toJson(requestBody);
                if (!TextUtils.isEmpty(json_req_body)) {
                    JsonObject jo = gson.fromJson(json_req_body, JsonObject.class);
                    JsonArray encodedNames = (JsonArray) jo.get("encodedNames");
                    JsonArray encodedValues = (JsonArray) jo.get("encodedValues");
                    for (int index = 0, size = encodedNames.size(); index < size; index++) {
                        JsonElement name = encodedNames.get(index);
                        JsonElement value = encodedValues.get(index);
                        jo_post_param.add(name.toString(), value);
                    }
                }
            }

            String url_get = url_base + "?" + buffer.readString(charset);

            mDeviceCrashInfo.put("RequestStart", "[" + "" + "]" + "------------RequestStart----------");
            mDeviceCrashInfo.put("请求协议：", request.toString());
            mDeviceCrashInfo.put("基本地址：", url_base);
            mDeviceCrashInfo.put("请求报头：", request.headers());
            mDeviceCrashInfo.put("请求报文：", jo_post_param);
            mDeviceCrashInfo.put("请求格式：", requestBody != null ? requestBody.contentType() : "获取失败");
            mDeviceCrashInfo.put("拼接地址：", url_get);
            mDeviceCrashInfo.put("RequestEnd", "[" + "" + "]" + "------------RequestEnd----------");

            String response_str = response.toString();
            Response responseBody = response.networkResponse();

            mDeviceCrashInfo.put("ResponseStart", "[" + "" + "]" + "------------ResponseStart----------");
            mDeviceCrashInfo.put("响应协议：", response_str);
            mDeviceCrashInfo.put("响应报文：", responseBody);
            mDeviceCrashInfo.put("响应格式：", response.body().contentType());
            mDeviceCrashInfo.put("ResponseEnd", "[" + "" + "]" + "------------ResponseEnd----------");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mDeviceCrashInfo;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        return logForResponse(request, response);
    }

    private Response logForResponse(Request request, Response response) {
        try {
            Response.Builder builder = response.newBuilder();
            Response clone = builder.build();

            ResponseBody responseBody = response.body();
            BufferedSource source = responseBody.source();
            source.request(Long.MAX_VALUE);
            Buffer buffer = source.buffer();
            Charset charset = UTF8;
            if (responseBody.contentLength() != 0) {
                String resp = buffer.clone().readString(charset);
                if (resp.startsWith("int")) {//PHP服务端问题

                }
                printLongLog(tag, request, response, resp);
            }
            if (!TextUtils.isEmpty(clone.message())) {
                if (showResponse) {
                    ResponseBody body = clone.body();
                    if (body != null) {
                        MediaType mediaType = body.contentType();
                        if (mediaType != null) {
                            ///Log.e(tag, "responseBody's contentType : " + mediaType.toString());
                            if (isText(mediaType)) {
                                String resp = body.string();
//                                Log.e(tag, "responseBody's content : " + resp);

                                body = ResponseBody.create(mediaType, resp);
                                return response.newBuilder().body(body).build();
                            } else {
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;
    }

    private boolean isText(MediaType mediaType) {
        if (mediaType.type() != null && mediaType.type().equals("text")) {
            return true;
        }
        if (mediaType.subtype() != null) {
            if (mediaType.subtype().equals("json") ||
                    mediaType.subtype().equals("xml") ||
                    mediaType.subtype().equals("html") ||
                    mediaType.subtype().equals("webviewhtml")
            )
                return true;
        }
        return false;
    }

    private String bodyToString(final Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "something error when show requestBody.";
        }
    }
}
